<template>
  <div :class="['context-menu', showMenu && 'show']" :style="{ top, left }">
    <ul>
      <li
        v-for="item in items"
        :key="item.text"
        @click="(event: any) => handleItemClick(item.action)"
        @contextmenu="(event: any) => event.preventDefault()"
      >
        {{ item.text }}
      </li>
    </ul>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, provide, inject } from "vue";

interface ContextMenuItem {
  text: string;
  action: () => void;
}

export default defineComponent({
  name: "ContextMenu",
  props: {
    items: {
      type: Array as () => ContextMenuItem[],
      required: true,
    },
  },
  setup(props) {
    const showMenu = ref(false);
    const posX = ref(0);
    const posY = ref(0);

    const currShow = ref(false);

    provide("menu", this);

    inject("menu", (e: any) => {
      console.log(e);
    });

    // 处理菜单项点击事件
    const handleItemClick = (action: () => void) => {
      action && action();
      close();
    };

    // 开启菜单
    const open = () => {
      showMenu.value = true;
    };

    // 关闭菜单
    const close = () => {
      showMenu.value = false;
    };

    // 设置菜单位置
    const setPosition = (x: number, y: number) => {
      posX.value = x;
      posY.value = y;
    };

    return {
      showMenu,
      posX,
      posY,
      handleItemClick,
      open,
      close,
      setPosition,
    };
  },
  computed: {
    top() {
      return `${this.posY}px`;
    },
    left() {
      return `${this.posX}px`;
    },
  },
});
</script>

<style scoped>
.context-menu {
  position: fixed;
  z-index: 9999;
  /* display: none; */
  width: fit-content;
  top: 0;
  left: 0;
}

.context-menu.show {
  display: block;
  background: #fff;
  border: 1px solid #ccc;
  box-shadow: 0 3px 5px rgba(0, 0, 0, 0.3);
  list-style: none;
  margin: 0;
  padding: 0;
}

.context-menu.show ul {
  margin: 0;
  padding: 0;
}

.context-menu.show li {
  display: block;
  width: 100%;
  padding: 5px 20px;
  cursor: pointer;
  user-select: none;
}

.context-menu.show li:hover {
  background-color: #f5f5f5;
}
</style>
